package com.iotp.service.menu;

import com.iotp.dao.authority.AuthorityDAO;
import com.iotp.dao.menu.MenuDAO;
import com.iotp.entity.menu.Menu;
import com.iotp.service.base.BaseServiceImpl;
import com.iotp.utils.common.DataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;

/**
 * 系统菜单业务接口实现类
 * @author Assassin
 */
@Service("menuService")
public class MenuServiceImpl extends BaseServiceImpl implements MenuService {

	// Fields

	@Autowired
	private MenuDAO menuDAO;// 系统菜单DAO接口
	@SuppressWarnings("unused")
	@Autowired
	private AuthorityDAO authorityDAO;// 系统权限DAO接口

	// Methods

	/**
	* 添加系统菜单根菜单
	* @param menuType 标识信息-菜单类型
	* @param orgId 标识信息-机构Id
	* @param menuName 基本信息-菜单名称
	* @param aliasName 基本信息-菜单别名
	* @param menuIcon 基本信息-菜单图标
	* @param menuDesc 基本信息-菜单说明
	* @param menuUrl 授权信息-菜单URL
	* @param authPerms 授权信息-授权角色[ALL-全部]
	* @return Long menuId 添加后的数据库主键值
	*/
	@Override
	public Long addRoot(Integer menuType, Long orgId, String menuName, String aliasName, String menuIcon,
			String menuDesc, String menuUrl, String authPerms) {
		// 构造系统菜单参数实体
		Menu menu = new Menu();
		
		// 标识信息
		String menuCode = DataUtil.getMenuCode(queryCurrentMaxMenuCode(orgId, 1, 0L), null);// 添加根菜单menuLeve=1 & menuPid=0L
		menu.setMenuCode(menuCode);// Set 标识信息-菜单编码
		menu.setMenuType(menuType);// Set 标识信息-菜单类型
		menu.setOrgId(orgId);// Set 标识信息-机构Id
		
		// 状态信息
		menu.setMenuStatus(1);// Set 状态信息-菜单数据状态->默认数据状态=>1
		menu.setIsDel(0);// Set 状态信息-是否删除[1-是 | 0-否]->默认是否删除=>0
		menu.setMenuOrder(null);// Set 状态信息-菜单排序->默认排序=>null
		
		// 层级信息
		menu.setMenuLevel(1);// Set 层级信息-菜单层级->添加根菜单默认级别=>1
		menu.setIsParent(0);// Set 层级信息-是否父级[1-是 | 0-否]->新添加菜单默认是否父级=>0
		menu.setMenuPid(0L);// Set 层级信息-父级Id[ROOT-0]->添加根菜单默认父级Id=>0L
		
		// 基本信息
		menu.setMenuName(menuName);// Set 基本信息-菜单名称
		menu.setAliasName(aliasName);// Set 基本信息-菜单别名
		menu.setMenuIcon(menuIcon);// Set 基本信息-菜单图标
		menu.setMenuDesc(menuDesc);// Set 基本信息-菜单说明
		
		menu.setMenuUrl(menuUrl);// Set 授权信息-菜单URL
		menu.setAuthPerms(authPerms);// Set 授权信息-授权角色[ALL-全部]
		
		Long createTime = System.currentTimeMillis();// 默认创建时间->系统当前时间
		menu.setCreateTime(createTime);// Set 时间信息-创建时间
		menu.setUpdateTime(null);// Set 时间信息-更新时间[初始化=NULL]
		
		// 调用系统菜单DAO接口
		this.menuDAO.insert(menu);
		
		// 菜单添加成功同步权限信息
		this.syncAuthority(menuCode, orgId, menuName, menuDesc, authPerms, menuUrl, createTime);
		
		// 返回添加后的数据库主键值
		return menu.getMenuId();
	}
	
   /**
	* 添加系统菜单子菜单
	* @param menuPid 层级信息-父级Id[ROOT-0]
	* @param menuName 基本信息-菜单名称
	* @param aliasName 基本信息-菜单别名
	* @param menuIcon 基本信息-菜单图标
	* @param menuDesc 基本信息-菜单说明
	* @param menuUrl 授权信息-菜单URL
	* @param authPerms 授权信息-授权角色[ALL-全部]
	* @return Long menuId 添加后的数据库主键值
	*/
	@Override
	public Long addSub(Long menuPid, String menuName, String aliasName, String menuIcon, String menuDesc,
			String menuUrl, String authPerms) {
		// 构造系统菜单参数实体
		Menu menu = new Menu();
		// 查询父菜单信息
		Menu parentMenu = this.menuDAO.selectById(menuPid);
		Integer menuLevel = parentMenu.getMenuLevel() + 1;// 根据父菜单Id计算当前子菜单级别
		
		// 标识信息
		String menuCode = DataUtil.getMenuCode(queryCurrentMaxMenuCode(parentMenu.getOrgId(), menuLevel, menuPid), parentMenu.getMenuCode());
		menu.setMenuCode(menuCode);// Set 标识信息-菜单编码
		menu.setMenuType(parentMenu.getMenuType());// Set 标识信息-菜单类型
		menu.setOrgId(parentMenu.getOrgId());// Set 标识信息-机构Id
		
		// 状态信息
		menu.setMenuStatus(1);// Set 状态信息-菜单数据状态->默认数据状态=>1
		menu.setIsDel(0);// Set 状态信息-是否删除[1-是 | 0-否]->默认是否删除=>0
		menu.setMenuOrder(null);// Set 状态信息-菜单排序->默认排序=>null
		
		// 层级信息
		menu.setMenuLevel(menuLevel);// Set 层级信息-菜单层级->添加子菜单级别=>menuLevel
		menu.setIsParent(0);// Set 层级信息-是否父级[1-是 | 0-否]->新添加菜单默认是否父级=>0
		menu.setMenuPid(menuPid);// Set 层级信息-父级Id[ROOT-0]->添加子菜单父级Id=>menuPid
		
		// 基本信息
		menu.setMenuName(menuName);// Set 基本信息-菜单名称
		menu.setAliasName(aliasName);// Set 基本信息-菜单别名
		menu.setMenuIcon(menuIcon);// Set 基本信息-菜单图标
		menu.setMenuDesc(menuDesc);// Set 基本信息-菜单说明
		
		menu.setMenuUrl(menuUrl);// Set 授权信息-菜单URL
		menu.setAuthPerms(authPerms);// Set 授权信息-授权角色[ALL-全部]
		
		Long createTime = System.currentTimeMillis();// 默认创建时间->系统当前时间
		menu.setCreateTime(createTime);// Set 时间信息-创建时间
		menu.setUpdateTime(null);// Set 时间信息-更新时间[初始化=NULL]
		
		// 调用系统菜单DAO接口
		this.menuDAO.insert(menu);
		
		// 菜单添加成功同步权限信息
		this.syncAuthority(menuCode, parentMenu.getOrgId(), menuName, menuDesc, authPerms, menuUrl, createTime);
		
		// 子菜单添加成功，更新父级菜单信息
		if(parentMenu.getIsParent().intValue() == 0) {
			editIsParent(parentMenu.getMenuId(), 1);
		}
		
		// 返回添加后的数据库主键值
		return menu.getMenuId();
	}

   /**
	* 删除系统菜单
	* @param menuId 主键值
	*/
	@Override
	public void delete(Long menuId) {
		// 调用系统菜单DAO接口
		this.menuDAO.delete(menuId);
	}

   /**
	* 更新系统菜单
	* @param menuId 标识信息-菜单Id
	* @param menuStatus 状态信息-菜单数据状态
	* @param isDel 状态信息-是否删除[1-是 | 0-否]
	* @param menuOrder 状态信息-菜单排序
	* @param menuName 基本信息-菜单名称
	* @param aliasName 基本信息-菜单别名
	* @param menuIcon 基本信息-菜单图标
	* @param menuDesc 基本信息-菜单说明
	* @param menuUrl 授权信息-菜单URL
	* @param authPerms 授权信息-授权角色[ALL-全部]
	*/
	@Override
	public void edit(Long menuId, Integer menuStatus, Integer isDel, Integer menuOrder, String menuName,
			String aliasName, String menuIcon, String menuDesc, String menuUrl, String authPerms) {
	    // 构造系统菜单参数实体
		Menu menu = new Menu();
		menu.setMenuId(menuId);// Set 标识信息-菜单Id[主键值]
		menu.setMenuStatus(menuStatus);// Set 状态信息-菜单数据状态
		menu.setIsDel(isDel);// Set 状态信息-是否删除[1-是 | 0-否]
		menu.setMenuOrder(menuOrder);// Set 状态信息-菜单排序
		menu.setMenuName(menuName);// Set 基本信息-菜单名称
		menu.setAliasName(aliasName);// Set 基本信息-菜单别名
		menu.setMenuIcon(menuIcon);// Set 基本信息-菜单图标
		menu.setMenuDesc(menuDesc);// Set 基本信息-菜单说明
		menu.setMenuUrl(menuUrl);// Set 授权信息-菜单URL
		menu.setAuthPerms(authPerms);// Set 授权信息-授权角色[ALL-全部]
		menu.setUpdateTime(System.currentTimeMillis());// Set 时间信息-更新时间[初始化=NULL]
		// 调用系统菜单DAO接口
		this.menuDAO.update(menu);
	}

   /**
	* 主键查询系统菜单
	* @param menuId 主键值
	* @return Menu 实体
	*/
	@Override
	public Menu queryById(Long menuId) {
		// 调用系统菜单DAO接口
		return this.menuDAO.selectById(menuId);
	}

   /**
	* 根据条件查询系统菜单列表
	* @param menuId 标识信息-菜单Id[主键值]
	* @param menuCode 标识信息-菜单编码
	* @param menuType 标识信息-菜单类型
	* @param orgId 标识信息-机构Id
	* @param menuStatus 状态信息-菜单数据状态
	* @param isDel 状态信息-是否删除[1-是 | 0-否]
	* @param menuOrder 状态信息-菜单排序
	* @param menuLevel 层级信息-菜单层级
	* @param isParent 层级信息-是否父级[1-是 | 0-否]
	* @param menuPid 层级信息-父级Id[ROOT-0]
	* @param menuName 基本信息-菜单名称
	* @param aliasName 基本信息-菜单别名
	* @param menuIcon 基本信息-菜单图标
	* @param menuDesc 基本信息-菜单说明
	* @param menuUrl 授权信息-菜单URL
	* @param authPerms 授权信息-授权角色[ALL-全部]
	* @param createTime 时间信息-创建时间
	* @param updateTime 时间信息-更新时间[初始化=NULL]
	* @return List<Menu> 实体List
	*/
	@Override
	public List<Menu> queryList(Long menuId, String menuCode, Integer menuType, Long orgId, Integer menuStatus,
			Integer isDel, Integer menuOrder, Integer menuLevel, Integer isParent, Long menuPid, String menuName,
			String aliasName, String menuIcon, String menuDesc, String menuUrl, String authPerms, Long createTime,
			Long updateTime) {
		// 构造系统菜单参数实体
		Menu menu = new Menu();
		menu.setMenuId(menuId);// Set 标识信息-菜单Id[主键值]
		menu.setMenuCode(menuCode);// Set 标识信息-菜单编码
		menu.setMenuType(menuType);// Set 标识信息-菜单类型
		menu.setOrgId(orgId);// Set 标识信息-机构Id
		menu.setMenuStatus(menuStatus);// Set 状态信息-菜单数据状态
		menu.setIsDel(isDel);// Set 状态信息-是否删除[1-是 | 0-否]
		menu.setMenuOrder(menuOrder);// Set 状态信息-菜单排序
		menu.setMenuLevel(menuLevel);// Set 层级信息-菜单层级
		menu.setIsParent(isParent);// Set 层级信息-是否父级[1-是 | 0-否]
		menu.setMenuPid(menuPid);// Set 层级信息-父级Id[ROOT-0]
		menu.setMenuName(menuName);// Set 基本信息-菜单名称
		menu.setAliasName(aliasName);// Set 基本信息-菜单别名
		menu.setMenuIcon(menuIcon);// Set 基本信息-菜单图标
		menu.setMenuDesc(menuDesc);// Set 基本信息-菜单说明
		menu.setMenuUrl(menuUrl);// Set 授权信息-菜单URL
		menu.setAuthPerms(authPerms);// Set 授权信息-授权角色[ALL-全部]
		menu.setCreateTime(createTime);// Set 时间信息-创建时间
		menu.setUpdateTime(updateTime);// Set 时间信息-更新时间[初始化=NULL]
		// 调用系统菜单DAO接口
		return this.menuDAO.selectList(menu);
	}
	
	/**
	 * 编辑菜单状态（逻辑删除 | 恢复）
	 * @param menuId 菜单Id
	 * @param isDel 是否删除状态
	 */
	@Override
	public void editIsDel(Long menuId, Integer isDel) {
		// 删除前加载出菜单信息
		Menu menu = this.menuDAO.selectById(menuId);
		HashMap<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("menuId", menuId);
		paramsMap.put("isDel", isDel);
		paramsMap.put("updateTime", System.currentTimeMillis());
		this.menuDAO.updateIsDel(paramsMap);
		// 逻辑删除
		if(isDel.intValue() == 1) {
			// 更新父级菜单信息
			if(menu.getMenuPid() != null && menu.getMenuPid().longValue() != 0L) {
				List<Menu> psubList = querySubList(menu.getMenuPid());
				if(psubList == null || psubList.size() == 0) {
					this.editIsParent(menu.getMenuPid(), 0);
				}
			}
			// 更新子级菜单信息->同步所有子菜单删除状态
			if(menu.getIsParent().intValue() == 1) {
				HashMap<String, Object> subParamsMap = new HashMap<String, Object>();
				subParamsMap.put("menuPid", menu.getMenuId());
				subParamsMap.put("isDel", isDel);
				subParamsMap.put("updateTime", System.currentTimeMillis());
				this.menuDAO.updateIsDelByPid(subParamsMap);
			}
			// 所有子集都删除后，更新自身是否父级属性
			this.editIsParent(menuId, 0);
		}
	}
	
	/**
	 * 根据父Id查询子菜单信息
	 * @param menuPid 父菜单Id
	 * @return List<Menu>
	 */
	@Override
	public List<Menu> querySubList(Long menuPid) {
		HashMap<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("menuPid", menuPid);
		paramsMap.put("isDel", 0);
		return this.menuDAO.selectSubList(paramsMap);
	}
	
	/**
	 * 查询角色对应的菜单信息
	 * @param roleId 角色Id
	 * @return List<Menu>
	 */
	@Override
	public List<Menu> queryMenuByRoleId(Long roleId) {
		return this.menuDAO.selectMenuByRoleId(roleId);
	}
	
	/**
	 * 根据属性验证菜单是否存在
	 * @param menuId 菜单Id
	 * @param menuName 菜单名称
	 * @param menuUrl 菜单URL
	 * @return List<Menu>
	 */
	@Override
	public List<Menu> queryIsMenuExist(Long menuId, String menuName, String menuUrl) {
		HashMap<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("menuId", menuId);
		paramsMap.put("menuName", menuName);
		paramsMap.put("menuUrl", menuUrl);
		return this.menuDAO.selectIsMenuExist(paramsMap);
	}
	
	/**
	 * 根据菜单级别和父菜单Id查询当前数据库菜单最大编码
	 * @param orgId
	 * @param menuLelve
	 * @param menuPid
	 * @return currentMaxMenuCode
	 */
	private String queryCurrentMaxMenuCode(Long orgId, Integer menuLelve, Long menuPid) {
		HashMap<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("orgId", orgId);
		paramsMap.put("menuLelve", menuLelve);
		paramsMap.put("menuPid", menuPid);
		return this.menuDAO.selectCurrentMaxMenuCode(paramsMap);
	}
	
	/**
	 * 更新菜单是否父级信息
	 * @param menuId 菜单Id
	 * @param isParent 是否父级
	 */
	private void editIsParent(Long menuId, Integer isParent) {
		HashMap<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("menuId", menuId);
		paramsMap.put("isParent", isParent);
		paramsMap.put("updateTime", System.currentTimeMillis());
		this.menuDAO.updateIsParent(paramsMap);
	}
	
	/**
	 * 同步菜单权限到权限数据表
	 * @param menuCode 菜单编码->同步给权限编码
	 * @param orgId 机构Id
	 * @param menuName 菜单名称->同步给权限名称
	 * @param menuDesc 菜单说明->同步给权限说明
	 * @param authPerms 菜单权限标识->同步给权限标识
	 * @param menuUrl 菜单URL->同步给权限地址
	 * @param createTime 创建时间
	 */
	private void syncAuthority(String menuCode, Long orgId, String menuName, String menuDesc, String authPerms,
			String menuUrl, Long createTime) {
//		Authority authority = new Authority(null, menuCode, 2, orgId, null, null, 0, null, 0, 0, 0L, menuName, menuDesc,
//				authPerms, menuUrl, createTime, null);
//		this.authorityDAO.insert(authority);
	}
	
}